package com.gitee.wsl.ext.list

fun <T> MutableList<T>.swap(i: Int, j: Int): MutableList<T> {
    this[i] = this[j].also { this[j] = this[i] }
    return this
}

fun <T> List<T>.swapped(index:Int, toPosition: Int): List<T> {
    val l = toMutableList()
    l.swap(index,toPosition)
    return l.toList()
}


fun <T> MutableList<T>.reverse(fromIndex: Int, toIndex: Int) {
    if (fromIndex < 0 || toIndex > size) {
        throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex, size: $size")
    }
    if (fromIndex > toIndex) {
        throw IllegalArgumentException("fromIndex: $fromIndex > toIndex: $toIndex")
    }
    val midPoint = (fromIndex + toIndex) / 2
    if (fromIndex == midPoint) return
    var reverseIndex = toIndex - 1
    for (index in fromIndex until midPoint) {
        val tmp = this[index]
        this[index] = this[reverseIndex]
        this[reverseIndex] = tmp
        reverseIndex--
    }
}


/**
 * Swaps the elements at [idx1] and [idx2] by creating a new list.
 *
 * If idx1 or idx2 is out of bounds, the list is returned as is.
 */
fun <E> List<E>.swapAt(idx1: Int, idx2: Int): List<E> {

    if (idx1 < 0 || idx1 >= size || idx2 < 0 || idx2 >= size || idx1 == idx2) {
        return this
    }

    val mutable = toMutableList()

    val tmp = mutable[idx1]
    mutable[idx1] = mutable[idx2]
    mutable[idx2] = tmp

    return mutable.toList()
}